using System;
using System.Data.Common;
using EPiServer.Common.Data;

namespace EPiServer.Templates.RelatePlus.Templates.PageEntity
{
    public class PageEntityProvider : IEntityProvider
    {
        private static readonly PageEntityProvider _entityProviderInstance = new PageEntityProvider();

        /// <summary>
        /// Gets the provider instance.
        /// </summary>
        /// <returns></returns>
        public static IEntityProvider GetProviderInstance()
        {
            return _entityProviderInstance;
        }

        #region IEntityProvider Members

        /// <summary>
        /// Gets the entity instance.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public object GetEntityInstance(Type type, int id)
        {
            ValidateIsSupportedType(type);
            
            return PageEntityHandler.GetPageEntity(id);
        }

        /// <summary>
        /// Gets the entity instance.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="reader">The reader.</param>
        /// <returns></returns>
        public object GetEntityInstance(Type type, DbDataReader reader)
        {
            ValidateIsSupportedType(type);
            
            return ConstructPageEntity(type, reader);
        }

        #endregion

        #region Helper methods

        private void ValidateIsSupportedType(Type type)
        {
            if (type.IsSubclassOf(typeof(PageEntity)))
            {
                // Type is a descendant of PageEntity, that is: ArticlePageEntity, DocumentPageEntity or similar
                return;
            }

            throw new NotSupportedException(String.Format("The type '{0}' is not supported by this provider.", type.ToString()));
        }
        /// <summary>
        /// Constructs the page reference entity.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="reader">The reader.</param>
        /// <returns></returns>
        private PageEntity ConstructPageEntity(Type type, DbDataReader reader)
        {
            // First Column in db is ID of entity and in our case the pageID.
            Guid pageGuid = reader.GetGuid(0);

            int id = reader.GetInt32(1);
            int siteID = reader.GetInt32(3);

            return (PageEntity)Activator.CreateInstance(type, new object[] { id, siteID, pageGuid });
        }
        #endregion
    }
}